/*
 * Copyright (c) 2019. 郑州仁中和科技有限公司.保留所有权利. 
http://www.rzhkj.com/ 
郑州仁中和科技有限公司保留所有代码著作权.如有任何疑问请访问官方网站与我们联系. 代码只针对特定客户使用，不得在未经允许或授权的情况下对外传播扩散.恶意传播者，法律后果自行承担.
 */
package com.ponddy.core.enums;

import java.io.Serializable;

/**
 * Copyright 2019 @http://www.rzhkj.com
 *
 * @Author borong
 * @Date 2019/8/9 20:28
 * @Description: http 状态码
 * 1**	信息，服务器收到请求，需要请求者继续执行操作
 * 2**	成功，操作被成功接收并处理
 * 3**	重定向，需要进一步的操作以完成请求
 * 4**	客户端错误，请求包含语法错误或无法完成请求
 * 5**	服务器错误，服务器在处理请求的过程中发生了错误
 * <p>
 * 状态码（状态码的英文名称，状态码的中文描述）
 */
public enum HttpCodeEnum implements Serializable {

    // 1**	信息，服务器收到请求，需要请求者继续执行操作
    code_100(100, "Continue", "继续。客户端应继续其请求"),
    code_101(101, "Switching Protocols", "切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议，例如，切换到HTTP的新版本协议"),

    // 2**	成功，操作被成功接收并处理
    code_200(200, 1786275283548528640L, "OK", "请求成功"),
    code_201(201, "Created", "已创建。成功请求并创建了新的资源"),
    code_202(202, "Accepted", "已接受。已经接受请求，但未处理完成"),
    code_203(203, "Non-Authoritative Information", "非授权信息。请求成功。但返回的meta信息不在原始的服务器，而是一个副本"),
    code_204(204, "No Content", "无内容。服务器成功处理，但未返回内容。在未更新网页的情况下，可确保浏览器继续显示当前文档"),
    code_205(205, "Reset Content", "重置内容。服务器处理成功，用户终端（例如：浏览器）应重置文档视图。可通过此返回码清除浏览器的表单域"),
    code_206(206, "Partial Content", "部分内容。服务器成功处理了部分GET请求"),

    // 3**	重定向，需要进一步的操作以完成请求
    code_300(300, "Multiple Choices", "多种选择。请求的资源可包括多个位置，相应可返回一个资源特征与地址的列表用于用户终端（例如：浏览器）选择"),
    code_301(301, "Moved Permanently", "永久移动。请求的资源已被永久的移动到新URI，返回信息会包括新的URI，浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替"),
    code_302(302, "Found", "临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI"),
    code_303(303, "See Other", "查看其它地址。与301类似。使用GET和POST请求查看"),
    code_304(304, "Not Modified", "未修改。所请求的资源未修改，服务器返回此状态码时，不会返回任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源"),
    code_305(305, "Use Proxy", "使用代理。所请求的资源必须通过代理访问"),
    code_306(306, "Unused", "已经被废弃的HTTP状态码"),
    code_307(307, "Temporary Redirect", "临时重定向。与302类似。使用GET请求重定向"),

    // 4**	客户端错误，请求包含语法错误或无法完成请求
    code_400(400, "Bad Request", "客户端请求的语法错误，服务器无法理解"),
    code_401(401, "Unauthorized", "请求要求用户的身份认证"),
    code_402(402, "Payment Required", "保留，将来使用"),
    code_403(403, "Forbidden", "服务器理解请求客户端的请求，但是拒绝执行此请求"),
    code_404(404, "Not Found", "服务器无法根据客户端的请求找到资源（网页）。通过此代码，网站设计人员可设置\"您所请求的资源无法找到\"的个性页面"),
    code_405(405, "Method Not Allowed", "客户端请求中的方法被禁止"),
    code_406(406, "Not Acceptable", "服务器无法根据客户端请求的内容特性完成请求"),
    code_407(407, "Proxy Authentication Required", "请求要求代理的身份认证，与401类似，但请求者应当使用代理进行授权"),
    code_408(408, "Request Time-out", "服务器等待客户端发送的请求时间过长，超时"),
    code_409(409, "Conflict", "服务器完成客户端的 PUT 请求时可能返回此代码，服务器处理请求时发生了冲突"),
    code_410(410, "Gone", "客户端请求的资源已经不存在。410不同于404，如果资源以前有现在被永久删除了可使用410代码，网站设计人员可通过301代码指定资源的新位置"),
    code_411(411, "Length Required", "服务器无法处理客户端发送的不带Content-Length的请求信息"),
    code_412(412, "Precondition Failed", "客户端请求信息的先决条件错误"),
    code_413(413, "Request Entity Too Large", "由于请求的实体过大，服务器无法处理，因此拒绝请求。为防止客户端的连续请求，服务器可能会关闭连接。如果只是服务器暂时无法处理，则会包含一个Retry-After的响应信息"),
    code_414(414, "Request-URI Too Large", "请求的URI过长（URI通常为网址），服务器无法处理"),
    code_415(415, "Unsupported Media Type", "服务器无法处理请求附带的媒体格式"),
    code_416(416, "Requested range not satisfiable", "客户端请求的范围无效"),
    code_417(417, "Expectation Failed", "服务器无法满足Expect的请求头信息"),

    // 5**	服务器错误，服务器在处理请求的过程中发生了错误
    code_500(500, "Internal Server Error", "服务器内部错误，无法完成请求"),
    code_501(501, "Not Implemented", "服务器不支持请求的功能，无法完成请求"),
    code_502(502, "Bad Gateway", "作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应"),
    code_503(503, "Service Unavailable", "由于超载或系统维护，服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中"),
    code_504(504, "Gateway Time-out", "充当网关或代理的服务器，未及时从远端服务器获取请求"),
    code_505(505, "HTTP Version not supported", "服务器不支持请求的HTTP协议的版本，无法完成处理"),

    /**
     * ---以下是自定义状态码----------------------------------------------------------------------------------------------
     */
    code_31(31, 1786383310565957632L, "服务器异常；"),
    code_32(32, "业务异常；"),
    code_33(33, "未知异常！"),
    code_41(41, "http post请求异常"),
    code_42(42, "http get请求异常"),
    code_43(43, "枚举类型未定义"),
    code_37(37, "重复操作"),
    code_44(44, "您的请求已被服务器阻挡"),
    code_45(45, "JSON对象格式无效"),
    code_46(46, "JSON集合格式无效"),
    code_47(47, "账号或密码错误，请重新输入"),
    code_48(48, ""),
    code_49(49, ""),

    //-----------------统一处理异常相关，定义[4000~4200]--------------------------
    code_4000(4000, "空指针异常"),
    code_4001(4001, "控制器方法参数类型不匹配；原因为 => "),
    code_4002(4002, "数据库相关异常；原因为 => "),
    code_4003(4003, "Mybatis相关异常；原因为 => "),
    code_4004(4004, "数据类型转换异常；原因为 => "),
    code_4005(4005, "对象装箱异常；原因为 => "),
    code_4006(4006, "参数异常；原因为 => "),
    code_4007(4007, "参数异常；原因为 => "),
    code_4008(4008, "参数异常；原因为 => "),

    //-----------------数据检查类代号 定义[50~70]--------------------------
    code_50(50, "格式错误"),
    code_51(51, "格式错误，并提醒正确格式"),
    code_52(52, 1786285402491478016L, "某参数为空"),
    code_53(53, "某参数值无效"),
    code_54(54, "对象为空"),
    code_55(55, "某对象不存在"),
    code_56(56, "某对象已存在"),
    code_57(57, "某某已经设置"),
    code_58(58, "添加失败"),
    code_59(59, "字节长度超限"),
    code_60(60, "长度超限"),
    code_61(61, "区间长度超限"),
    code_62(62, "上传的文件为空"),
    code_63(63, "正在认证审核中，请耐心等待..."),
    code_64(64, "已认证；如要修改信息，请联系管理员；"),
    code_65(65, "尚未申请认证"),
    code_66(66, "响应结果数据校验失败"),
    code_67(67, "元素正在被使用，不允许删除"),
    code_68(68, ""),
    code_69(69, ""),
    code_70(70, ""),
    //-----------------账户登录异常，需要重新登录 定义[71~79]--------------------------
    code_71(71, "会话过期，请重新登录"),
    code_72(72, "会话异常，请重新登录"),
    code_73(73, "会话无效，请重新登录"),
    code_74(74, "账号被冻结，请联系管理员"),
    code_75(75, ""),
    code_76(76, ""),
    code_77(77, ""),
    code_78(78, ""),
    code_79(79, ""),
    //-----------------文件相关异常，需要重新登录 定义[80~85]--------------------------
    code_80(80, "上传的文件有点大喽"),
    code_81(81, ""),
    code_82(82, ""),
    code_83(83, ""),
    code_84(84, ""),
    code_85(85, ""),
    //-----------------消息相关异常，需要重新登录 定义[80~85]--------------------------
    code_86(86, "短信发送失败"),
    code_87(87, "验证码已过期"),
    code_88(88, "验证码无效"),
    code_89(89, "验证码无效"),
    //-----------------微信相关异常，定义[91~100]--------------------------
    code_91(91, "当前微信号已绑定其它用户"),
    code_92(92, "请移驾去绑定微信"),
    code_93(93, "加密数据解密失败"),


    //-----------------订单/商品相关异常，定义[1001~1099]--------------------------
    code_1001(1001, "请选择一个区域"),
    code_1002(1002, "请确定收货人信息"),
    code_1003(1003, "请预约一个服务时间"),
    code_1004(1004, "订单创建失败，请重试"),
    code_1005(1005, "订单支付失败，请确认订单状态"),
    code_1006(1006, "购物车无数据"),
    code_1007(1007, "请确认支付电子币"),
    code_1008(1008, "电子币余额不足"),
    code_1009(1009, "金额为负"),
    code_1010(1010, "请选择一个服务类型"),
    code_1011(1011, "很遗憾，差一点就抢到了，请您继续关注..."),
    code_1012(1012, "此单暂无分配服务人员，不能开始服务"),
    code_1013(1013, "此单暂无分配服务人员，不能完成服务"),
    code_1014(1014, "电子币支付太少"),
    code_1015(1015, "此订单不允许继续申请售后"),
    code_1016(1016, "此订单不允许继续审核"),
    code_1017(1017, "未知的售后处理结果"),
    code_1018(1018, "售后单退款失败"),
    code_1019(1019, "订单没有第三方支付"),
    code_1020(1020, "获取的订单支付金额有误"),
    code_1021(1021, "此订单不允许发货"),
    code_1022(1022, "此订单已付款"),
    code_1023(1023, "此订单已关闭"),
    code_1024(1024, "此订单不能确认收货"),
    code_1025(1025, "支付回调业务类型未检查"),

    //-----------------支付相关异常，定义[201~299]--------------------------
    code_2001(2001, "微信-统一下单-接口请求失败 => "),
    code_2002(2002, "微信-申请退款-接口请求失败=> "),
    code_2003(2003, "微信-支付交易状态查询-接口请求失败 => "),
    code_2004(2004, "微信-关闭订单-接口请求失败 => "),
    code_2005(2005, "微信-签名-接口请求失败 => "),
    code_2006(2006, "微信-沙箱签名-接口请求失败 => "),
    code_2007(2007, "微信-企业转账-接口请求失败 => "),
    code_2008(2008, "支付宝-统一下单-接口请求失败 => "),
    code_2009(2009, "支付宝-申请退款-接口请求失败 => "),
    code_2010(2010, "支付宝-支付交易状态查询-接口请求失败 => "),
    code_2011(2011, "支付宝-关闭订单-接口请求失败 => "),
    code_2012(2012, "支付宝-签名-接口请求失败 => "),


    //-----------------业务[商城]相关异常，定义[3000~3099]--------------------------
    code_3000(3000, "加入购物车商品的数量不正确"),

    //-----------------业务相关异常，定义[500~599]--------------------------

    //-----------------RBAC 相关异常，定义[9000~9099]--------------------------
    code_9000(9000, "菜单重名"),
    code_9001(9001, "存在子集，不能删除"),
    code_9002(9002, "权限不足"),
    code_9003(9003, "原密码不正确"),
    code_9004(9004, "超管不允许操作"),
    code_9005(9005, "不允许删除"),
    ;

    /**
     * 状态码
     */
    public int code;

    /**
     * i18n项目 键代码
     */
    public Long i18nKeyCode;

    /**
     * 状态码英文名称
     */
    public String enName;

    /**
     * 中文描述
     */
    public String zhName;

    /**
     * HTTP状态码 枚举键 的前缀
     */
    private final static String HTTP_CODE_ENUM_PREFIX = "code_";

    HttpCodeEnum() {
        code = getCode(this.name());
    }

    HttpCodeEnum(String enName, String zhName) {
        this.enName = enName;
        this.zhName = zhName;
    }

    HttpCodeEnum(int code, String zhName) {
        this.zhName = zhName;
        this.code = code;
    }

    HttpCodeEnum(int code, String enName, String zhName) {
        this.enName = enName;
        this.zhName = zhName;
        this.code = code;
    }

    HttpCodeEnum(int code, Long i18nKeyCode, String zhName) {
        this.code = code;
        this.i18nKeyCode = i18nKeyCode;
        this.zhName = zhName;
    }

    HttpCodeEnum(int code, Long i18nKeyCode, String enName, String zhName) {
        this.code = code;
        this.i18nKeyCode = i18nKeyCode;
        this.enName = enName;
        this.zhName = zhName;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    /**
     * 通过HTTP请求状态码获取枚举
     *
     * @param code HTTP 请求状态码
     * @return
     */
    public static HttpCodeEnum getEnum(int code) {
        for (HttpCodeEnum enums : HttpCodeEnum.values()) {
            if (getCode(enums.name()) - code == 0) {
                return enums;
            }
        }
        return null;
    }

    /**
     * 从英文状态中获得数字类型的状态码
     *
     * @param code 例：code_200
     * @return
     */
    private static int getCode(String code) {
        int codeStartIndex = HTTP_CODE_ENUM_PREFIX.length();
        return Integer.valueOf(code.substring(codeStartIndex));
    }
}